<template>
  <!-- 客户聊天端 -->
  <div class="customerService-box">
    <div class="box">
      <div class="title">
        <span class="title-text">在线客服</span>
      </div>
      <div ref="contentRef" class="content-info">
        <div
          class="content-info-item"
          v-for="(item, index) in infoArr"
          :key="index"
        >
          <div class="info_r info_default" v-if="item.type == 'leftinfo'">
            <img class="avatar" src="@/assets/image/robot.jpg" alt />
            <div class="info_r_content">
              <p class="robot-name">在线客服</p>
              <div class="con_r con_text">
                <!-- <div
                  class="img-box"
                  v-if="item.messageType === 'img'"
                  v-html="item.content"
                ></div> -->
                <el-image
                  :teleported="true"
                  v-if="item.messageType === 'img'"
                  style="width: 12.5em; height: 6.25em"
                  :src="item.content"
                  :preview-src-list="[item.content]"
                  fit="cover"
                />
                <div
                  class="pedding-text"
                  v-else-if="item.messageType === 'pedding'"
                >
                  <el-icon class="is-loading">
                    <Loading />
                  </el-icon>
                </div>
                <span v-else class="con_l">{{ item.content }}</span>
                <div v-for="(item2, index) in item.question" :key="index">
                  <div
                    class="con_que"
                    @click="clickRobot(item2.content, item2.id)"
                  >
                    <div class="question-msg">
                      {{ item2.index }}
                      {{ item2.content }}
                    </div>
                  </div>
                </div>
              </div>
              <div v-if="item.messageType !== 'pedding'" class="time_r">
                {{ item.time }}
              </div>
            </div>
          </div>

          <div class="info_l" v-if="item.type == 'rightinfo'">
            <div class="info_l_content">
              <div class="con_l con_text">
                <el-image
                  :teleported="true"
                  v-if="item.messageType === 'img'"
                  style="width: 12.5em; height: 6.25em"
                  :src="item.content"
                  :preview-src-list="[item.content]"
                  fit="cover"
                />
                <!-- <div
                  class="img-box"
                  v-if="item.messageType === 'img'"
                  v-html="item.content"
                ></div> -->
                <span v-else>{{ item.content }}</span>
              </div>
              <div class="time_l">{{ item.time }}</div>
            </div>
            <img src="@/assets/image/user.png" class="avatar" />
          </div>
          <div class="info-tips" v-if="item.type == 'tips'">
            {{ item.content }}
          </div>
        </div>
      </div>
      <!-- <span class="messag-loading" v-show="loading">消息发送中</span> -->
      <div class="common-info">
        <div
          class="common-item"
          @click="clickRobot(item.content, item.id)"
          v-for="item in robotQuestion"
          :key="item.id"
        >
          {{ item.content }}
        </div>
      </div>
      <ul class="tool-bar">
        <ChooseEmotion @getEmo="chooseEmo" />
        <img src="@/assets/image/SVG/picture.svg"  @click="chooseImg()" alt class="svg-icon mgl-16" />

        <!-- <svg-icon
          @click="chooseImg()"
          class="mgl-16"
          iconName="icon-tupian"
        ></svg-icon> -->
      </ul>

      <div class="setproblem">
        <el-input
          v-model="customerText"
          @keyup.enter="sentMsg()"
          style="
            height: 11.25em;
            width: 100%;
            resize: none;
            padding-right: 5em;
            outline: none;
            border-color: #ccc;
            border-radius: 0.32em;
            font-size: 1em;
          "
          resize="none"
          :rows="5"
          type="textarea"
          maxlength="200"
          placeholder="请输入您的问题（200字以内）"
        />
        <button @click="sentMsg()" type="primary">发 送</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, nextTick, onBeforeUnmount } from "vue";
import ChooseEmotion from "./ChooseEmotion.vue";
import { Loading } from "@element-plus/icons-vue";
import { uploadImg, queryChatInfo } from "@/utils/api/customerService/index";
import EventBus from "@/utils/eventBus.js";

const props = defineProps({
  robotName: {
    type: String,
    default: "",
  },
  serveBoxContent: {
    type: String,
    default: "",
  },
});
// let currentCustomerId = Math.floor(Math.random() * 900) + 100;
let currentCustomerId = "";
let receive_id = "";

const contentRef = ref();
// const loading = ref(false);
function generateRandom11DigitNumber() {
  var min = 10000000000; // 最小的11位数
  var max = 99999999999; // 最大的11位数
  var randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
  return randomNumber.toString(); // 转换为字符串表示
}
const getTodayTime = () => {
  // 获取当前时间
  var day = new Date();
  let seconds = day.getSeconds();
  if (seconds < 10) {
    seconds = "0" + seconds;
  } else {
    seconds = seconds;
  }
  let minutes = day.getMinutes();
  if (minutes < 10) {
    minutes = "0" + minutes;
  } else {
    minutes = minutes;
  }
  let time =
    day.getFullYear() +
    "-" +
    (day.getMonth() + 1) +
    "-" +
    day.getDate() +
    " " +
    day.getHours() +
    ":" +
    minutes +
    ":" +
    seconds;
  return time;
};
const peddingObj = {
  type: "leftinfo",
  time: getTodayTime(),
  name: "robot",
  content: "",
  question: [],
  messageType: "pedding",
};
const robotQuestion = [
  { id: 1, content: "什么是AISEO", index: 1 },
  { id: 2, content: "AISEO能做什么", index: 2 },
];
const robotAnswer = [
  {
    id: 1,
    content: "AISEOWORD是成都柳暗星河科技有限公司旗下品牌，致力于一站式解决网络推广中的各种难题",
    index: 1,
  },
  { id: 2, content: "AISEOWORD为用户提供文案撰写、SEO定制、软文推广、网站优化和网站联运五大服务，您也可以描述具体问题，我们将为您定制专属服务方案。", index: 2 },
];
const infoArr = ref([
  {
    type: "leftinfo",
    time: getTodayTime(),
    name: "robot",
    content: `您好，欢迎使用AISEO，为保证账户安全，在会话过程中请勿透露您的账号、密码。`,
    question: [],
    messageType: "txt",
  },
]);
// 选择表情
const chooseEmo = (cur) => {
  customerText.value += cur;
};
// 用户发送消息
const customerText = ref("");
let timer = null;
const endMsg = () => {
  let happyEnding = {
    type: "leftinfo",
    time: getTodayTime(),
    content: "会话结束",
    question: [],
    messageType: "txt",
  };
  infoArr.value.push(happyEnding);
  clearInterval(timerInterVal);
  nextTick(() => {
    contentRef.value?.scrollTo({
      top: contentRef.value.scrollHeight,
      behavior: "smooth",
    });
  });
  socket.close();
};
const networkErroshibrMsg = () => {
  clearTimeout(timer);
  let happyEnding = {
    type: "leftinfo",
    time: getTodayTime(),
    content: "连接出错。。。",
    question: [],
    messageType: "txt",
  };
  //   infoArr.value.push(happyEnding);
  infoArr.value[infoArr.value.length - 1] = happyEnding;
  nextTick(() => {
    contentRef.value?.scrollTo({
      top: contentRef.value.scrollHeight,
      behavior: "smooth",
    });
  });
};
// 用户发送消息
const sentMsg = () => {
  if (!window.WebSocket) {
    return;
  }
  let text = customerText.value.trim();
  if (text != "") {
    // var obj = {
    //   type: "rightinfo",
    //   time: getTodayTime(),
    //   content: text,
    //   messageType: "txt",
    // };
    // if (infoArr.value[infoArr.value.length - 1].messageType === "pedding") {
    //   infoArr.value[infoArr.value.length - 1] = obj;
    // } else {
    //   infoArr.value.push(obj);
    // }
    appendRobotMsg(customerText.value);
    // nextTick(() => {
    //   contentRef.value?.scrollTo({
    //     top: contentRef.value.scrollHeight,
    //     behavior: "smooth",
    //   });
    // });
  }
};
const showTimer = () => {
  timer = setTimeout(() => {
    endMsg();
  }, 1000 * 60);
};
const appendRobotMsg = (text) => {
  text = text.trim();
  let answerText = "";
  let flag;
  for (let i = 0; i < robotQuestion.length; i++) {
    if (robotQuestion[i].content === text) {
      flag = true;
      answerText = robotAnswer.find(
        (dd) => dd.id == robotQuestion[i].id
      ).content;
      break;
    }
  }
  customerText.value = "";
  // infoArr.value.push(peddingObj);
  if (flag) {
    let obj = {
      type: "leftinfo",
      time: getTodayTime(),
      name: "robot",
      content: answerText,
      question: [],
      messageType: "txt",
    };
    if (infoArr.value[infoArr.value.length - 1].messageType === "pedding") {
      infoArr.value[infoArr.value.length - 1] = obj;
    } else {
      infoArr.value.push(obj);
    }
  } else {
    sendMsgToServe({
      message: text,
      messageType: "txt",
      mode: "single",
      receive_id: receive_id, //用户类型
      type: "chat",
      sendId: currentCustomerId,
    });
  }
  nextTick(() => {
    contentRef.value?.scrollTo({
      top: contentRef.value.scrollHeight,
      behavior: "smooth",
    });
  });
};
const sentMsgById = (val, id) => {
  //   clearTimeout(timer);
  //   showTimer();

  let robotById = robotAnswer.filter((item) => {
    return item.id == id;
  });
  let obj_l = {
    type: "leftinfo",
    time: getTodayTime(),
    name: "robot",
    content: robotById[0].content,
    question: [],
    messageType: "txt",
  };
  let obj_r = {
    type: "rightinfo",
    time: getTodayTime(),
    name: "robot",
    content: val,
    question: [],
    messageType: "txt",
  };
  infoArr.value.push(obj_r);
  infoArr.value.push(obj_l);
  nextTick(() => {
    contentRef.value?.scrollTo({
      top: contentRef.value.scrollHeight,
      behavior: "smooth",
    });
  });
};
// 点击机器人的单个问题
const clickRobot = (val, id) => {
  sentMsgById(val, id);
};
let socket = null;
let timerInterVal = null;
const initWebsoket = (callback) => {
  if (!window.WebSocket) {
    window.WebSocket = window.MozWebSocket;
  }
  if (window.WebSocket) {
    // 获取当前页面的完整URL  
var currentURL = window.location.href;  
  
  // 使用URL API解析URL  
  var urlObject = new URL(currentURL);  
    
  // 获取协议部分（例如：http: 或 https:）  
  var protocol = urlObject.protocol;  
  const { public: { websoketChatUrl } } = useRuntimeConfig()
  if (protocol === 'http:') {
    socket = new WebSocket(`ws://${websoketChatUrl}/ws`);
  }
  if (protocol === 'https:') {
    socket = new WebSocket(`wss://${websoketChatUrl}`);
    
  }
    socket.onmessage = function (event) {
      if (!event) return;
      try {
        let data = JSON.parse(event.data || "{}");
        /*
        判断条件 1. 排除null可能性
                 2. 确保数据是对象或数组
    */
        if (data && typeof data === "object") {
          if (data?.type === "chat") {
            let obj = {
              type: "leftinfo",
              time: getTodayTime(),
              name: "robot",
              content: data?.message ?? "",
              question: [],
              messageType: data?.messageType ?? "text",
            };
            if (
              infoArr.value[infoArr.value.length - 1].messageType === "pedding"
            ) {
              infoArr.value[infoArr.value.length - 1] = obj;
            } else {
              infoArr.value.push(obj);
            }
            nextTick(() => {
              contentRef.value?.scrollTo({
                top: contentRef.value.scrollHeight,
                behavior: "smooth",
              });
            });
          }
        }
      } catch {}
    };
    socket.onopen = function (event) {
      if (callback) {
        callback();
      }
      //发送心跳
      clearInterval(timerInterVal);
      timerInterVal = setInterval((res) => {
        if (socket?.readyState === WebSocket.OPEN) {
          socket.send(JSON.stringify({ type: "ping" }));
        } else {
          clearInterval(timerInterVal);
        }
      }, 10000);
      socket.send(JSON.stringify({ type: "bind", id: currentCustomerId })); //绑定聊天对象
      infoArr.value.push({
        type: "tips",
        content: `连接已开启`,
      });
      // 发送打招呼语句
      if (props.serveBoxContent) {
        sendMsgToServe({
          message: props.serveBoxContent,
          messageType: "txt",
          mode: "single",
          receive_id: receive_id, //用户类型
          type: "chat",
          sendId: currentCustomerId,
        });
      }
    };
    socket.onclose = function (event) {
      // endMsg();
      infoArr.value.push({
        type: "tips",
        content: `连接已断开`,
      });
      nextTick(() => {
        contentRef.value?.scrollTo({
          top: contentRef.value.scrollHeight,
          behavior: "smooth",
        });
      });
    };
    socket.onerror = function (error) {
      clearTimeout(timer);
      //   loading.value = false;
      networkErroshibrMsg();
    };
  } else {
    alert("你的浏览器不支持WebSocket");
  }
};
const upLoadImgs = (file) => {
  return new Promise((resolve, reject) => {
    let formData = new FormData();
    formData.append("file", file);
    const isLt = file.size / 1024;
    if (isLt > 300) {
      // ElNotification({
      //   title: "发送失败",
      //   message: "上传文件大小不能超过 300KB!",
      //   type: "warning",
      // });
      EventBus.emit('openToastBox', ["上传文件大小不能超过 300KB！"])
      reject("文件过大");
      return false;
    }
    uploadImg(formData)
      .then((res) => {
        resolve(res);
      })
      .catch(() => {
        reject();
      });
  });
};
const chooseImg = (role) => {
  let input = document.createElement("input");
  input.setAttribute("type", "file");
  // 支持多选
  input.setAttribute("multiple", "multiple");
  input.accept = "image/*";
  input.addEventListener("change", async (e) => {
    // let file = e.path[0].files[0];
    let file = e.currentTarget.files[0];
    upLoadImgs(file)
      .then((resData) => {
        let res = JSON.parse(resData.data.value);
        if (res?.code === 200) {
          const runtimeInfo = useRuntimeConfig()
          let fileUploadUrl = runtimeInfo.public.fileUploadUrl
          let imgSrc =
          fileUploadUrl + res?.src;
          // 浏览器兼容性处理（有的浏览器仅存在 Window.URL）
          const windowURL = window.URL || window.webkitURL;
          // 发送给后端
          sendMsgToServe({
            message: imgSrc,
            messageType: "img",
            mode: "single",
            receive_id: receive_id, //用户类型
            type: "chat",
            sendId: currentCustomerId,
          });
        } else {
          // ElNotification({
          //   title: "发送失败",
          //   message: res.msg,
          //   type: "error",
          // });
          EventBus.emit('openToastBox', ["发送失败！"])
        }
      })
      .catch((error) => {
        if (error !== "文件过大") {
          // ElNotification({
          //   title: "",
          //   message: "发送失败",
          //   type: "error",
          // });
          EventBus.emit('openToastBox', ["发送失败！"])
        }
      });
  });
  input.click();
};

const sendMsgToServe = (obj, isShow = true) => {
  var inofObj = {
    type: "rightinfo",
    time: getTodayTime(),
    content: obj.message,
    messageType: obj.messageType,
  };
  if (socket?.readyState === WebSocket.OPEN) {
    // 发送给后端
    socket.send(JSON.stringify(obj));
    isShow && infoArr.value.push(inofObj);
  } else {
    if (currentCustomerId) {
      initWebsoket(() => {
        if (socket?.readyState === WebSocket.OPEN) {
          socket.send(JSON.stringify(obj));
          isShow && infoArr.value.push(inofObj);
        } else {
          clearTimeout(timer);
        }
      });
    } else {
      initSessionInfo(() => {
        if (socket?.readyState === WebSocket.OPEN) {
          socket.send(JSON.stringify(obj));
          isShow && infoArr.value.push(inofObj);
        } else {
          clearTimeout(timer);
        }
      });
    }
  }
  if (isShow) {
    nextTick(() => {
      contentRef.value?.scrollTo({
        top: contentRef.value.scrollHeight,
        behavior: "smooth",
      });
    });
  }
};
const initSessionInfo = (callback) => {
  let current = localStorage.getItem(props.robotName + "aiseo-seesion-info"); //存数
  if (!current) {
    queryChatInfo({
      user_id: "tourist",
    })
      .then((response) => {
        let res = JSON.parse(response.data.value);
        if (res?.code === 200) {
          let resData = res.result;
          // 暂时取第一个客服
          let receiveInfo = resData?.receive_data?.[0] || {};
          current = {
            userId: resData?.user_id,
            robotId: receiveInfo.id,
            robotName: receiveInfo.username,
            remark: receiveInfo.remarks,
          };
          localStorage.setItem(
            props.robotName + "aiseo-seesion-info",
            JSON.stringify(current)
          );
          currentCustomerId = current?.userId;
          receive_id = current?.robotName;
          initWebsoket(callback);
        } else {
          // ElNotification({
          //   title: "连接错误！",
          //   message: "连接错误，请稍后重试！",
          //   type: "error",
          // });
          EventBus.emit('openToastBox', ["我帅"])

        }
      })
      .catch((erro) => {
        // ElNotification({
        //   title: "连接错误！",
        //   message: erro,
        //   type: "error",
        // });
        EventBus.emit('openToastBox', ["连接错误！"])

      });
  } else {
    current = JSON.parse(current);
    currentCustomerId = current?.userId;
    receive_id = current?.robotName;
    initWebsoket(callback);
  }
};

//切换窗口时
const visibilityCurrentWin = () => {};
onMounted(() => {
  if (process.client) {
    initSessionInfo();
    document.addEventListener("visibilitychange", handleChangeChatVisible);
  }
});
const handleChangeChatVisible = () => {
  if (document.visibilityState == "hidden") {
    // 给客服端提示
    sendMsgToServe(
      {
        message: "用户已离开",
        messageType: "tips",
        mode: "single",
        receive_id: receive_id, //用户类型
        type: "chat",
        sendId: currentCustomerId,
      },
      false
    );
  }
  if (document.visibilityState == "visible") {
    // 给客服端提示
    sendMsgToServe(
      {
        message: "用户已接入",
        messageType: "tips",
        mode: "single",
        receive_id: receive_id, //用户类型
        type: "chat",
        sendId: currentCustomerId,
      },
      false
    );
  }
};

onBeforeUnmount(() => {
     // 给客服端提示
     sendMsgToServe(
      {
        message: "用户已离开",
        messageType: "tips",
        mode: "single",
        receive_id: receive_id, //用户类型
        type: "chat",
        sendId: currentCustomerId,
      },
      false
    );
  clearInterval(timerInterVal);
  document.removeEventListener("visibilitychange", handleChangeChatVisible);
  socket?.close();
});
</script>

<style lang="scss" scoped>
.customerService-box {
  width: 100%;
  height: 100%;
  font-size: 1em;

  // box-shadow: 0 0.25em 0.5em rgba(0, 0, 0, 0.2);
  // border-radius: 0.5em;
  overflow: hidden;
  .box {
    width: 100%;
    height: 100%;
    background-color: #fafafa;
    position: relative;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    .title {
      text-align: center;
      background: #e62e3c;

      .title-text {
        font-weight: bold;
        line-height: 3em;
        font-size: 1em;
        color: #fff;
      }
    }
    .content-info {
      flex: 1;
      overflow-y: auto;
      font-size: 0.875em;
      width: 100%;
      padding: 1em 1.25em;
      box-sizing: border-box;
      &::-webkit-scrollbar {
        width: 0.375em;
        height: 0.375em;
        background: transparent;
      }

      &::-webkit-scrollbar-thumb {
        background: transparent;
        border-radius: 0.25em;
      }

      &:hover::-webkit-scrollbar-thumb {
        background: hsla(0, 0%, 53%, 0.4);
      }

      &:hover::-webkit-scrollbar-track {
        background: hsla(0, 0%, 53%, 0.1);
      }
      .content-info-item {
        & + .content-info-item {
          margin-top: 1.25em;
        }
      }
      .info_default {
        & + .info_default {
          margin-top: 1.25em;
        }
      }
      .avatar {
        width: 2.125em;
        height: 2.125em;
        border-radius: 1.6em;
      }
      .circle {
        display: inline-block;
        width: 2.125em;
        height: 2.125em;
        border-radius: 50%;
        background-color: #eff1f3;
      }
      .con_text {
        color: #333;
        margin-bottom: 0.32em;
        width: 100%;
        .img-box {
          width: 15em;
        }
      }
      .con_que {
        height: 1.875em;
        line-height: 1.875em;
        cursor: pointer;
      }
      .info_r {
        position: relative;
        display: flex;
        .info_r_content {
          display: inline-block;
          margin-left: 1em;
          .robot-name {
            margin-bottom: 0.25em;
            color: #999;
          }
          .circle_r {
            position: absolute;
            left: 0%;
          }
          .pic_r {
            width: 1em;
            height: 1em;
            margin: 0.5em;
          }
          .con_r {
            background-color: #eee;
            border-radius: 0.375em;
            padding: 0.75em 1em;
            box-sizing: border-box;
            overflow: auto;
          }
          .time_r {
            color: #999;
            font-size: 0.75em;
          }
        }
      }
      .info_l {
        display: flex;
        justify-content: flex-end;
        .info_l_content {
          margin-right: 1em;
        }
        .pic_l {
          width: 0.75em;
          height: 1em;
          margin: 0.5em 1.6em;
        }
        .time_l {
          color: #999999;
          font-size: 0.75em;
          margin-top: 0.32em;
          text-align: right;
        }
        .con_l {
          display: inline-block;
          width: 100%;
          background-color: #e62e3c;
          border-radius: 0.375em;
          padding: 0.75em 1em;
          color: #fff;
          box-sizing: border-box;
        }
      }
      .info-tips {
        text-align: center;
        font-size: 0.75em;
        color: #ccc;
      }
      #question {
        cursor: pointer;
      }
      .pedding-text {
        text-align: center;
      }
    }
    .setproblem {
      width: 100%;
      background-color: #ffffff;
      position: relative;
      :deep(.el-textarea) {
        .el-textarea__inner {
          box-shadow: none !important;
          border-radius: 0.5em;
          font-size: 1em;
        }
      }
    }
    .setproblem button {
      width: 4.5em;
      height: 2em;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1em;
      position: absolute;
      right: 5%;
      bottom: 1.25em;
      background-color: #e62e3c;
      border: none;
      border-radius: 0.5em;
      color: #fff;
    }
    .question-msg {
      float: left;
      font-size: 10.25em;
      color: #3c9cf3;
    }
    .messag-loading {
      color: #ccc;
      font-size: 0.75em;
      position: absolute;
      bottom: 150.5em;
      left: 50%;
      transform: translateX(-50%);
    }
    .common-info {
      display: flex;
      .common-item {
        border: 1px solid #ccc;
        border-radius: 0.5em;
        padding: 2px 0.25em;
        background: #fff;
        color: #aaa;
        font-size: 0.8em;
        cursor: pointer;
        // & + .common-item{
        margin-left: 0.5em;
        // }
      }
    }
    .tool-bar {
      display: flex;
      align-items: center;
      background: #fff;
      border-bottom: 1px solid #ccc;
      height: 2em;
      padding-left: 0.5em;
      .svg-icon {
        width: 1em;
        // font-size: 1em;
        cursor: pointer;
      }
      .mgl-16 {
        margin-left: 0.75em;
      }
    }
  }
}
</style>
